/**
 * 文件操作工具类
 */
package com.flute.framework.util;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;

import com.flute.framework.StandardDate;
import com.flute.framework.data.constants.Constants;

/**
 * @author Jazz
 * 
 */
public final class FileToolsUtil {
	private static Logger logger = Logger.getLogger(FileToolsUtil.class);

	private FileToolsUtil() {
		throw new RuntimeException("Cannot instance FileToolsUtil class");
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {

	}

	/**
	 * 得到日期文件名
	 * 
	 * @param fileName
	 *            是带有后缀的文件名 比如 1280125018436.xml
	 * @return String 返回不带有最后的日期文件名 2010-07-26
	 */
	public static String getDateFileName(String fileName)
			throws NumberFormatException {
		fileName = getNameWithoutSuffix(fileName);
		StandardDate date = new StandardDate(Long.parseLong(fileName));
		String dateFileName = date
				.toDateStringByPattern(Constants.DATE_PATTERN);
		return dateFileName;
	}

	public static boolean isValidXMLFile(String fileName) {
		return fileName.endsWith(Constants.XML_SUFFIX);
	}

	/**
	 * 得到文件名
	 * 
	 * @param fileName
	 *            是带有后缀的文件名 比如 1280125018436.xml
	 * @return String 返回不带有最后的文件名 1280125018436
	 */
	public static String getNameWithoutSuffix(String name) {
		if (!StringUtils.contains(name, ".")) {
			throw new IllegalArgumentException("The name=" + name
					+ " is illegal.");
		}
		int dotIndex = name.lastIndexOf(".");
		return name.substring(0, dotIndex);
	}

	/**
	 * 源文件移动到目标文件
	 * 
	 * @param srcFile
	 *            源文件文件
	 * @param destFile
	 *            目标文件
	 */
	public static void moveFileToDestFile(File srcFile, File destFile) {
		try {
			FileUtils.moveFile(srcFile, destFile);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("Move " + srcFile.getName() + " failed");
		}
	}

	/**
	 * 源文件移动到目标文件目录
	 * 
	 * @param srcFile
	 *            源文件文件
	 * @param destDir
	 *            目标文件目录
	 * @throws IOException
	 */
	public static void moveFileToDir(File srcFile, File destDir)
			throws IOException {
		try {
			FileUtils.moveFileToDirectory(srcFile, destDir, Boolean.TRUE);
		} catch (IOException e) {
			logger.error("Move " + srcFile.getName() + " failed");
			throw new IOException("移动 " + srcFile.getName() + " 失败");
		}
	}

	public static void moveSrcDirToDestDir(File srcDir, File destDir)
			throws IOException {
		try {
			FileUtils.moveDirectoryToDirectory(srcDir, destDir, Boolean.TRUE);
		} catch (IOException e) {
			logger.error("Move " + srcDir.getName() + " failed");
			throw new IOException("移动 " + srcDir.getName() + " 失败");
		}
	}

	public static void copySrcDirToDestDir(File srcDir, File destDir) {
		try {
			FileUtils.copyDirectoryToDirectory(srcDir, destDir);
		} catch (IOException e) {
			e.printStackTrace();
			logger.error("Copy " + srcDir.getName() + " to "
					+ destDir.getName() + " failed");
		}
	}

	public static File[] getAllDateDirsUnderPath(String path) {
		if (StringUtils.isNotEmpty(path)) {
			File file = new File(path);
			File[] dateDirs = file.listFiles();
			return dateDirs;
		}
		return new File[] {};
	}

	public static List<File> getDateDirByStandardDate(String path,
			StandardDate date) {
		File[] allDateDirs = getAllDateDirsUnderPath(path);
		List<File> dateDirs = new ArrayList<File>();
		if (allDateDirs == null || allDateDirs.length == 0) {
			return dateDirs;
		}
		String folderName = date.toDateStringByPattern(Constants.DATE_PATTERN);
		for (File dateDir : allDateDirs) {
			if (dateDir.isDirectory() && dateDir.getName().equals(folderName)) {
				dateDirs.add(dateDir);
			}
		}
		return dateDirs;
	}

	public static List<File> getAllFileBeforeStandardDate(String path,
			StandardDate date) {
		List<File> allFiles = new ArrayList<File>();
		List<File> allDirs = getDirBeforeDate(date, path);
		if (allDirs == null) {
			return allFiles;
		}
		allFiles.addAll(getAllFile(allDirs));
		return allFiles;
	}

	private static List<File> getDirBeforeDate(StandardDate date, String path) {
		File[] allDirs = getAllDateDirsUnderPath(path);
		List<File> dirBeforeDate = new ArrayList<File>();
		if (allDirs != null && allDirs.length != 0) {
			StandardDate dateOfDir = null;
			for (File dir : allDirs) {
				if (dir.isDirectory()) {
					try {
						dateOfDir = new StandardDate(dir.getName(),
								Constants.DATE_PATTERN);
						if (dateOfDir.isBefore(date)) {
							dirBeforeDate.add(dir);
						}
					} catch (ParseException e) {
						e.printStackTrace();
						logger.error("Parser date " + dir.getName()
								+ " is error");
					}
				}
			}
		}
		return dirBeforeDate;
	}

	public static List<File> getAllFileByStandardDate(String path,
			StandardDate date) {
		List<File> allFiles = new ArrayList<File>();
		List<File> allDirs = getDateDirByStandardDate(path, date);
		if (allDirs == null) {
			return allFiles;
		}
		allFiles.addAll(getAllFile(allDirs));
		return allFiles;
	}

	public static String getFileNameByPath(String path) {
		File typeFileDir = new File(path);
		String fileName = typeFileDir.getName();
		return fileName;
	}

	private static List<File> getAllFile(List<File> dateDirs) {
		List<File> allFiles = new ArrayList<File>();
		for (File dateDir : dateDirs) {
			if (dateDir.isDirectory() && !dateDir.isHidden()) {
				File[] files = dateDir.listFiles();
				for (File file : files) {
					if (!file.isDirectory()) {
						allFiles.add(file);
					}
				}
			}
		}
		return allFiles;
	}

	public static List<File> getAllFileUnderPath(String path) {
		List<File> allFiles = new ArrayList<File>();
		File[] allDirs = getAllDateDirsUnderPath(path);
		if (allDirs == null) {
			return allFiles;
		}
		List<File> allDirsList = Arrays.asList(allDirs);
		allFiles.addAll(getAllFile(allDirsList));
		Collections.sort(allFiles, new FileComparator());
		return allFiles;
	}

	private static class FileComparator implements Comparator<File>,
			Serializable {
		private static final long serialVersionUID = 3299648670285375694L;

		@Override
		public int compare(File o1, File o2) {
			String oName1 = o1.getName();
			String oName2 = o2.getName();
			return oName1.compareTo(oName2);
		}

	}

	/**
	 * 得到日期目录文件
	 * 
	 * @param fileName
	 *            文件名带有后缀 1280125018436.xml
	 * @param path
	 *            文件路径
	 * 
	 * @return File 返回日期目录文件
	 */
	public static File getDateDir(String fileName, String path) {
		String dateFolderName = FileToolsUtil.getDateFileName(fileName);
		File dateFolder = new File(path + File.separator + dateFolderName);
		return dateFolder;
	}

}
